package com.mask.encryption.autoconfigure;

import com.mask.encryption.config.MaskEncryptionProperties;
import com.mask.encryption.service.MaskEncryptionService;
import com.mask.encryption.service.impl.AesGcmEncryptionService;
import com.mask.encryption.service.impl.RsaOaepEncryptionService;
import com.mask.encryption.service.impl.HybridRsaAesEncryptionService;
import com.mask.encryption.config.MaskEncryptionWebProperties;
import com.mask.encryption.web.MaskDecryptRequestBodyAdvice;
import com.mask.encryption.web.MaskEncryptResponseBodyAdvice;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;

import java.util.Base64;

@Configuration
@EnableConfigurationProperties({MaskEncryptionProperties.class, MaskEncryptionWebProperties.class})
public class MaskEncryptionAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean(MaskEncryptionService.class)
    @ConditionalOnProperty(prefix = "mask.encryption", name = "algorithm", havingValue = "AES", matchIfMissing = true)
    public MaskEncryptionService aesEncryptionService(MaskEncryptionProperties props) {
        byte[] keyBytes = null;
        if (StringUtils.hasText(props.getAesKey())) {
            String key = props.getAesKey();
            try {
                // 尝试Base64
                keyBytes = Base64.getDecoder().decode(key);
            } catch (IllegalArgumentException ignore) {
                // 当作明文
                keyBytes = key.getBytes(java.nio.charset.StandardCharsets.UTF_8);
            }
        }
        return new AesGcmEncryptionService(keyBytes, props.getGcmTagLength());
    }

    @Bean
    @ConditionalOnMissingBean(MaskEncryptionService.class)
    @ConditionalOnProperty(prefix = "mask.encryption", name = "algorithm", havingValue = "RSA")
    public MaskEncryptionService rsaEncryptionService(MaskEncryptionProperties props) {
        if (!StringUtils.hasText(props.getRsaPublicKey()) || !StringUtils.hasText(props.getRsaPrivateKey())) {
            throw new IllegalStateException("RSA algorithm requires rsaPublicKey and rsaPrivateKey");
        }
        return new RsaOaepEncryptionService(props.getRsaPublicKey(), props.getRsaPrivateKey());
    }

    @Bean
    @ConditionalOnMissingBean(MaskEncryptionService.class)
    @ConditionalOnProperty(prefix = "mask.encryption", name = "algorithm", havingValue = "HYBRID")
    public MaskEncryptionService hybridEncryptionService(MaskEncryptionProperties props) {
        if (!StringUtils.hasText(props.getRsaPublicKey()) || !StringUtils.hasText(props.getRsaPrivateKey())) {
            throw new IllegalStateException("HYBRID algorithm requires rsaPublicKey and rsaPrivateKey");
        }
        return new HybridRsaAesEncryptionService(props.getRsaPublicKey(), props.getRsaPrivateKey(), props.getGcmTagLength());
    }

    // Web 全局加解密组件（按需启用）
    @Bean
    @ConditionalOnProperty(prefix = "mask.encryption.web", name = "enabled", havingValue = "true")
    public MaskDecryptRequestBodyAdvice maskDecryptRequestBodyAdvice(MaskEncryptionService service, MaskEncryptionWebProperties webProps, javax.servlet.http.HttpServletRequest request) {
        return new MaskDecryptRequestBodyAdvice(service, webProps, request);
    }

    @Bean
    @ConditionalOnProperty(prefix = "mask.encryption.web", name = "enabled", havingValue = "true")
    public MaskEncryptResponseBodyAdvice maskEncryptResponseBodyAdvice(MaskEncryptionService service, MaskEncryptionWebProperties webProps, javax.servlet.http.HttpServletRequest request) {
        return new MaskEncryptResponseBodyAdvice(service, webProps, request);
    }
}


